//
// Created by 86135 on 2025-06-24.
//

#include <stdio.h>
#include <stdlib.h>
#include "semantic_analyzer.h"

// 辅助函数：检查二元表达式的类型兼容性
int checkBinaryExpressionType(ASTNode* left, ASTNode* right) {
    // 简单示例：假设只支持相同类型的操作
    if (left->type == right->type) {
        return 1; // 类型兼容
    }
    return 0; // 类型不兼容
}

// 语义分析函数
int semanticAnalysis(ASTNode* ast, SymbolTable* table) {
    if (ast == NULL) {
        return 1; // 空节点，认为语义正确
    }

    switch (ast->type) {
        case AST_PROGRAM:
            // 遍历所有声明
            for (int i = 0; i < ast->data.program.declCount; i++) {
                if (!semanticAnalysis(ast->data.program.declarations[i], table)) {
                    return 0;
                }
            }
            break;
        case AST_BINARY_EXPR:
            // 检查二元表达式的左右子节点类型兼容性
            if (!checkBinaryExpressionType(ast->data.binaryExpr.left, ast->data.binaryExpr.right)) {
                printf("Type error at line %d: Incompatible types in binary expression\n", ast->line);
                return 0;
            }
            // 递归分析左右子节点
            if (!semanticAnalysis(ast->data.binaryExpr.left, table) ||
                !semanticAnalysis(ast->data.binaryExpr.right, table)) {
                return 0;
            }
            break;
        case AST_DECLARATION:
            // 插入符号到符号表
            insertSymbol(table, ast->data.declaration.identifier->data.identifier.name, ast->data.declaration.typeSpec);
            // 递归分析初始化表达式
            if (ast->data.declaration.initExpr != NULL) {
                if (!semanticAnalysis(ast->data.declaration.initExpr, table)) {
                    return 0;
                }
            }
            break;
        case AST_IDENTIFIER:
            // 查找符号是否在符号表中
            SymbolTableEntry *entry = lookupSymbol(table, ast->data.identifier.name);
            if (entry == NULL) {
                printf("Error at line %d: Undefined identifier '%s'\n", ast->line, ast->data.identifier.name);
                return 0;
            }
            break;
            // 其他节点类型的处理...
        default:
            // 递归分析所有子节点
            for (int i = 0; i < ast->childCount; i++) {
                if (!semanticAnalysis(ast->children[i], table)) {
                    return 0;
                }
            }
            break;
    }

    return 1; // 语义正确
}